from rest_framework import serializers
from .models import User, Authentication  # 导入模型类


# 身份认证信息序列化器
class AuthenticationSerializer(serializers.ModelSerializer):
    # 显示活体检测状态的中文（如“认证成功”而非数字4）
    liveness_status_display = serializers.CharField(source="get_liveness_status_display", read_only=True)
    # 显示证件类型的中文（如“身份证”而非数字0）
    cert_type_display = serializers.CharField(source="get_cert_type_display", read_only=True)

    class Meta:
        model = Authentication  # 关联的模型
        # 需序列化的字段（核心业务字段，无补充字段）
        fields = [
            "id", "cert_type", "cert_type_display",  # 证件类型及中文显示
            "id_card_name", "id_card_number",  # 个人用户字段
            "license_company", "license_number",  # 企业用户字段
            "id_card_front", "id_card_back",  # 证件图片
            "ocr_result", "liveness_status", "liveness_status_display", "liveness_result",  # 认证相关
            "created_time", "updated_time"  # 时间字段
        ]
        read_only_fields = ["id", "created_time", "updated_time"]  # 主键和时间字段只读，不可修改


# 用户列表序列化器（用于列表页，仅展示核心字段）
class UserListSerializer(serializers.ModelSerializer):
    # 显示用户类型中文（如“个人”而非数字0）
    user_type_display = serializers.CharField(source="get_user_type_display", read_only=True)
    # 显示是否认证（映射id_verified字段）
    is_authenticated = serializers.BooleanField(source="id_verified", read_only=True)

    class Meta:
        model = User  # 关联的模型
        # 列表页展示的核心字段，减少数据传输
        fields = [
            "id", "username", "phone", "email",  # 基础信息
            "user_type", "user_type_display",  # 用户类型及中文显示
            "is_active", "is_authenticated", "created_time"  # 状态、认证情况、创建时间
        ]
        read_only_fields = ["id", "created_time"]  # 主键和创建时间只读


# 用户详情序列化器（用于详情页，展示完整信息及关联认证）
class UserDetailSerializer(serializers.ModelSerializer):
    # 嵌套序列化关联的认证信息（一对一关联）
    authentication = AuthenticationSerializer(read_only=True)
    # 显示用户类型中文
    user_type_display = serializers.CharField(source="get_user_type_display", read_only=True)
    # 显示是否认证
    is_authenticated = serializers.BooleanField(source="id_verified", read_only=True)

    class Meta:
        model = User  # 关联的模型
        # 详情页展示的完整字段，包含关联认证信息
        fields = [
            "id", "username", "phone", "email", "avatar",  # 基础信息+头像
            "user_type", "user_type_display", "is_active", "is_authenticated",  # 类型、状态、认证情况
            "created_time", "updated_time", "dingtalk_openid",  # 时间、钉钉OpenID
            "authentication"  # 关联的认证信息
        ]
        read_only_fields = ["id", "created_time", "updated_time"]  # 主键和时间字段只读


# 用户创建序列化器（用于用户注册，处理创建逻辑）
class UserCreateSerializer(serializers.ModelSerializer):
    # 注册时可同步提交认证信息（仅写入，不返回）
    authentication = AuthenticationSerializer(required=False, write_only=True)
    # 密码字段仅写入（不返回给前端，保障安全）
    password = serializers.CharField(write_only=True)

    class Meta:
        model = User  # 关联的模型
        # 创建用户需提交的字段
        fields = [
            "id", "username", "phone", "email", "password",  # 基础信息+密码
            "user_type", "avatar", "dingtalk_openid",  # 类型、头像、钉钉OpenID
            "authentication"  # 关联认证信息（可选）
        ]
        read_only_fields = ["id"]  # 主键自动生成，只读

    def create(self, validated_data):
        """创建用户时，同步创建关联的认证信息"""
        # 从提交数据中提取认证信息（如有）
        auth_data = validated_data.pop("authentication", None)
        # 创建用户（使用Django内置方法，自动加密密码）
        user = User.objects.create_user(**validated_data)
        # 若提交了认证信息，同步创建认证记录
        if auth_data:
            Authentication.objects.create(user=user, **auth_data)
        return user


# 用户更新序列化器（用于修改用户信息，处理更新逻辑）
class UserUpdateSerializer(serializers.ModelSerializer):
    # 可部分更新认证信息（可选，支持部分字段修改）
    authentication = AuthenticationSerializer(required=False, partial=True)
    # 密码字段可选更新，仅写入
    password = serializers.CharField(write_only=True, required=False)

    class Meta:
        model = User  # 关联的模型
        # 可更新的字段
        fields = [
            "username", "phone", "email", "password",  # 基础信息+密码（可选）
            "avatar", "user_type", "is_active", "dingtalk_openid",  # 头像、类型、状态、钉钉OpenID
            "authentication"  # 关联认证信息（可选）
        ]

    def update(self, instance, validated_data):
        """更新用户时，同步更新关联的认证信息"""
        # 提取认证信息和密码（如有）
        auth_data = validated_data.pop("authentication", None)
        password = validated_data.pop("password", None)

        # 更新用户基本信息
        for attr, value in validated_data.items():
            setattr(instance, attr, value)
        # 若更新密码，使用内置方法加密
        if password:
            instance.set_password(password)
        instance.save()

        # 处理认证信息更新
        if auth_data:
            # 若用户已有认证信息，直接更新
            if hasattr(instance, "authentication"):
                auth_instance = instance.authentication
                for attr, value in auth_data.items():
                    setattr(auth_instance, attr, value)
                auth_instance.save()
            # 若用户无认证信息，创建一条
            else:
                Authentication.objects.create(user=instance, **auth_data)
        return instance